package net.media.datafw.transport.transporters;

import java.io.ByteArrayInputStream;
import java.io.StringWriter;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import net.media.datafw.transport.TransportException;
import net.media.datafw.transport.Transporter;
import net.media.datafw.transport.model.TransportField;
import net.media.datafw.transport.model.Transportable;
import net.media.datafw.transport.utils.TransporterUtil;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;

public class XMLTransporter extends Transporter {
	private static final String ROOT_ELEMENT = "root";
	private static final String XML_ARRAYLIST_ITEM = "item";
	private static final String XML_HASHMAP_ITEM_NAME = "key";
	private static final String ROOT_IS_ARRAY = "isarray";
	Document document = null;
	DocumentBuilder documentBuilder = null;

	@Override
	protected void writeTransportable(Transportable data, Object serilizedData) throws TransportException {
		try {
			Element transportableObject = document.createElement(readClassName(data.getClass()));
			serializeTransportable(data, transportableObject);
			((Element) serilizedData).appendChild(transportableObject);
		} catch (Exception e) {
			throw new TransportException(e);
		}

	}

	@Override
	protected void writeTransportableArray(Transportable[] data, Object serilizedData) throws TransportException {
		try {
			if (data != null) {
				for (int i = 0; i < data.length; i++) {
					writeTransportable(data[i], serilizedData);
				}
			}
		} catch (Exception e) {
			throw new TransportException(e);
		}
	}

	@Override
	protected void serializeTransportable(TransportField field, Object objectData, Object serializedData) throws TransportException {
		try {
			if (field.isArray()) {
				Transportable[] transportableArray = (Transportable[]) objectData;
				Element transportableJSONArray = document.createElement(field.getArrayName());
				for (int i = 0; i < transportableArray.length; i++) {
					Element serializedTransportable = document.createElement(field.getName());
					Element transportableObject = document.createElement(readClassName(objectData.getClass().getComponentType()));
					serializeTransportable((Transportable) transportableArray[i], transportableObject);
					serializedTransportable.appendChild(transportableObject);
					((Element) transportableJSONArray).appendChild(serializedTransportable);
				}
				((Element) serializedData).appendChild(transportableJSONArray);
			} else {
				Element serializedTransportable = document.createElement(field.getName());
				Element transportableObject = document.createElement(readClassName(objectData.getClass()));
				serializeTransportable((Transportable) objectData, transportableObject);
				serializedTransportable.appendChild(transportableObject);
				((Element) serializedData).appendChild(serializedTransportable);
			}
		} catch (Exception e) {
			throw new TransportException(e);
		}
	}

	@Override
	protected Object initialiseTrasportableArray() throws TransportException {

		if (document == null) {
			document = createDocument();
		}
		Element rootElement = document.createElement(ROOT_ELEMENT);
		rootElement.setAttribute(ROOT_IS_ARRAY, "true");
		return rootElement;
	}

	@Override
	protected Object initialiseTrasportable() throws TransportException {
		if (document == null) {
			document = createDocument();
		}
		Element rootElement = document.createElement(ROOT_ELEMENT);
		rootElement.setAttribute(ROOT_IS_ARRAY, "false");
		return rootElement;
	}

	private Document createDocument() throws TransportException {
		Document document = null;
		try {
			if (documentBuilder == null) {
				documentBuilder = createDocumentBuilder();
			}
			document = documentBuilder.newDocument();
		} catch (Exception e) {
			throw new TransportException(e);
		}
		return document;
	}

	private DocumentBuilder createDocumentBuilder() throws TransportException {
		try {
			DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
			return documentBuilder = documentBuilderFactory.newDocumentBuilder();
		} catch (Exception e) {
			throw new TransportException(e);
		}

	}

	@Override
	protected void serializeBoolean(TransportField field, Object objectData, Object serializedData) throws TransportException {
		try {
			Class<?> clazz;
			if (field.isArray()) {
				clazz = ((Class<?>) field.getType()).getComponentType();
				boolean[] data;
				if (clazz.isPrimitive()) {
					data = (boolean[]) objectData;
				} else {
					Boolean[] dataArr = (Boolean[]) objectData;
					data = TransporterUtil.converBooleanArray(dataArr);
				}

				Element arrayXMLData = document.createElement(field.getArrayName());
				for (int dataIdx = 0; dataIdx < data.length; dataIdx++) {
					Element arrayElement = document.createElement(field.getName());
					Text textNode = document.createTextNode(((Boolean) data[dataIdx]).toString());
					arrayElement.appendChild(textNode);
					arrayXMLData.appendChild(arrayElement);
				}
				((Element) serializedData).appendChild(arrayXMLData);
			} else {
				((Element) serializedData).setAttribute(field.getName(), ((Boolean) objectData).toString());
			}
		} catch (Exception e) {
			throw new TransportException(e);
		}
	}

	@Override
	protected void serializeByte(TransportField field, Object objectData, Object serializedData) throws TransportException {
		try {
			Class<?> clazz;
			if (field.isArray()) {
				clazz = ((Class<?>) field.getType()).getComponentType();
				byte[] data;
				if (clazz.isPrimitive()) {
					data = (byte[]) objectData;
				} else {
					Byte[] dataArr = (Byte[]) objectData;
					data = TransporterUtil.converByteArray(dataArr);
				}

				Element arrayXMLData = document.createElement(field.getArrayName());
				for (int dataIdx = 0; dataIdx < data.length; dataIdx++) {
					Element arrayElement = document.createElement(field.getName());
					Text textNode = document.createTextNode(((Byte) data[dataIdx]).toString());
					arrayElement.appendChild(textNode);
					arrayXMLData.appendChild(arrayElement);
				}
				((Element) serializedData).appendChild(arrayXMLData);
			} else {
				((Element) serializedData).setAttribute(field.getName(), ((Byte) objectData).toString());
			}
		} catch (Exception e) {
			throw new TransportException(e);
		}
	}

	@Override
	protected void serializeCharacter(TransportField field, Object objectData, Object serializedData) throws TransportException {
		try {
			Class<?> clazz;
			if (field.isArray()) {
				clazz = ((Class<?>) field.getType()).getComponentType();
				char[] data;
				if (clazz.isPrimitive()) {
					data = (char[]) objectData;
				} else {
					Character[] dataArr = (Character[]) objectData;
					data = TransporterUtil.converCharacterArray(dataArr);
				}

				Element arrayXMLData = document.createElement(field.getArrayName());
				for (int dataIdx = 0; dataIdx < data.length; dataIdx++) {
					Element arrayElement = document.createElement(field.getName());
					Text textNode = document.createTextNode(((Character) data[dataIdx]).toString());
					arrayElement.appendChild(textNode);
					arrayXMLData.appendChild(arrayElement);
				}
				((Element) serializedData).appendChild(arrayXMLData);
			} else {
				((Element) serializedData).setAttribute(field.getName(), ((Character) objectData).toString());
			}
		} catch (Exception e) {
			throw new TransportException(e);
		}
	}

	@Override
	protected void serializeShort(TransportField field, Object objectData, Object serializedData) throws TransportException {
		try {
			Class<?> clazz;
			if (field.isArray()) {
				clazz = ((Class<?>) field.getType()).getComponentType();
				short[] data;
				if (clazz.isPrimitive()) {
					data = (short[]) objectData;
				} else {
					Short[] dataArr = (Short[]) objectData;
					data = TransporterUtil.converShortArray(dataArr);
				}

				Element arrayXMLData = document.createElement(field.getArrayName());
				for (int dataIdx = 0; dataIdx < data.length; dataIdx++) {
					Element arrayElement = document.createElement(field.getName());
					Text textNode = document.createTextNode(((Short) data[dataIdx]).toString());
					arrayElement.appendChild(textNode);
					arrayXMLData.appendChild(arrayElement);
				}
				((Element) serializedData).appendChild(arrayXMLData);
			} else {
				((Element) serializedData).setAttribute(field.getName(), ((Short) objectData).toString());
			}
		} catch (Exception e) {
			throw new TransportException(e);
		}
	}

	@Override
	protected void serializeInteger(TransportField field, Object objectData, Object serializedData) throws TransportException {
		try {
			Class<?> clazz;
			if (field.isArray()) {
				clazz = ((Class<?>) field.getType()).getComponentType();
				int[] data;
				if (clazz.isPrimitive()) {
					data = (int[]) objectData;
				} else {
					Integer[] dataArr = (Integer[]) objectData;
					data = TransporterUtil.converIntegerArray(dataArr);
				}

				Element arrayXMLData = document.createElement(field.getArrayName());
				for (int dataIdx = 0; dataIdx < data.length; dataIdx++) {
					Element arrayElement = document.createElement(field.getName());
					Text textNode = document.createTextNode(((Integer) data[dataIdx]).toString());
					arrayElement.appendChild(textNode);
					arrayXMLData.appendChild(arrayElement);
				}
				((Element) serializedData).appendChild(arrayXMLData);
			} else {
				((Element) serializedData).setAttribute(field.getName(), ((Integer) objectData).toString());
			}
		} catch (Exception e) {
			throw new TransportException(e);
		}
	}

	@Override
	protected void serializeLong(TransportField field, Object objectData, Object serializedData) throws TransportException {
		try {
			Class<?> clazz;
			if (field.isArray()) {
				clazz = ((Class<?>) field.getType()).getComponentType();
				long[] data;
				if (clazz.isPrimitive()) {
					data = (long[]) objectData;
				} else {
					Long[] dataArr = (Long[]) objectData;
					data = TransporterUtil.converLongArray(dataArr);
				}

				Element arrayXMLData = document.createElement(field.getArrayName());
				for (int dataIdx = 0; dataIdx < data.length; dataIdx++) {
					Element arrayElement = document.createElement(field.getName());
					Text textNode = document.createTextNode(((Long) data[dataIdx]).toString());
					arrayElement.appendChild(textNode);
					arrayXMLData.appendChild(arrayElement);
				}
				((Element) serializedData).appendChild(arrayXMLData);
			} else {
				((Element) serializedData).setAttribute(field.getName(), ((Long) objectData).toString());
			}
		} catch (Exception e) {
			throw new TransportException(e);
		}
	}

	@Override
	protected void serializeFloat(TransportField field, Object objectData, Object serializedData) throws TransportException {
		try {
			Class<?> clazz;
			if (field.isArray()) {
				clazz = ((Class<?>) field.getType()).getComponentType();
				float[] data;
				if (clazz.isPrimitive()) {
					data = (float[]) objectData;
				} else {
					Float[] dataArr = (Float[]) objectData;
					data = TransporterUtil.converFloatArray(dataArr);
				}

				Element arrayXMLData = document.createElement(field.getArrayName());
				for (int dataIdx = 0; dataIdx < data.length; dataIdx++) {
					Element arrayElement = document.createElement(field.getName());
					Text textNode = document.createTextNode(((Float) data[dataIdx]).toString());
					arrayElement.appendChild(textNode);
					arrayXMLData.appendChild(arrayElement);
				}
				((Element) serializedData).appendChild(arrayXMLData);
			} else {
				((Element) serializedData).setAttribute(field.getName(), ((Float) objectData).toString());
			}
		} catch (Exception e) {
			throw new TransportException(e);
		}
	}

	@Override
	protected void serializeDouble(TransportField field, Object objectData, Object serializedData) throws TransportException {
		try {
			Class<?> clazz;
			if (field.isArray()) {
				clazz = ((Class<?>) field.getType()).getComponentType();
				double[] data;
				if (clazz.isPrimitive()) {
					data = (double[]) objectData;
				} else {
					Double[] dataArr = (Double[]) objectData;
					data = TransporterUtil.converDoubleArray(dataArr);
				}

				Element arrayXMLData = document.createElement(field.getArrayName());
				for (int dataIdx = 0; dataIdx < data.length; dataIdx++) {
					Element arrayElement = document.createElement(field.getName());
					Text textNode = document.createTextNode(((Double) data[dataIdx]).toString());
					arrayElement.appendChild(textNode);
					arrayXMLData.appendChild(arrayElement);
				}
				((Element) serializedData).appendChild(arrayXMLData);
			} else {
				((Element) serializedData).setAttribute(field.getName(), ((Double) objectData).toString());
			}
		} catch (Exception e) {
			throw new TransportException(e);
		}
	}

	@Override
	protected void serializeString(TransportField field, Object objectData, Object serializedData) throws TransportException {
		try {
			if (field.isArray()) {
				String[] data = (String[]) objectData;

				Element arrayXMLData = document.createElement(field.getArrayName());
				for (int dataIdx = 0; dataIdx < data.length; dataIdx++) {
					Element arrayElement = document.createElement(field.getName());
					Text textNode = document.createTextNode((String) data[dataIdx]);
					arrayElement.appendChild(textNode);
					arrayXMLData.appendChild(arrayElement);
				}
				((Element) serializedData).appendChild(arrayXMLData);
			} else {
				((Element) serializedData).setAttribute(field.getName(), (String) objectData);
			}
		} catch (Exception e) {
			throw new TransportException(e);
		}
	}

	@Override
	protected void serializeDate(TransportField field, Object objectData, Object serializedData) throws TransportException {
		try {
			if (field.isArray()) {
				Date[] data = (Date[]) objectData;

				Element arrayXMLData = document.createElement(field.getArrayName());
				for (int dataIdx = 0; dataIdx < data.length; dataIdx++) {
					Element arrayElement = document.createElement(field.getName());
					Text textNode = document.createTextNode(data[dataIdx].toString());
					arrayElement.appendChild(textNode);
					arrayXMLData.appendChild(arrayElement);
				}
				((Element) serializedData).appendChild(arrayXMLData);
			} else {
				((Element) serializedData).setAttribute(field.getName(), objectData.toString());
			}
		} catch (Exception e) {
			throw new TransportException(e);
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	protected void serializeArrayList(TransportField field, Object objectData, Object serializedData) throws TransportException {
		try {
			Class<?> genericValueClass = (Class<?>) field.getComponentValueType();

			if (field.isArray()) {
				ArrayList<Object>[] data = (ArrayList<Object>[]) objectData;
				Element serializedDataArrayObject = document.createElement(field.getArrayName());
				for (int dataIdx = 0; dataIdx < data.length; dataIdx++) {
					Element serializedDataArray = document.createElement(field.getName());
					processArrayList(field, data[dataIdx], genericValueClass, serializedDataArray);
					((Element) serializedDataArrayObject).appendChild(serializedDataArray);
				}
				((Element) serializedData).appendChild(serializedDataArrayObject);
			} else {
				ArrayList<Object> data = (ArrayList<Object>) objectData;
				Element serializedDataArray = document.createElement(field.getName());
				processArrayList(field, data, genericValueClass, serializedDataArray);
				((Element) serializedData).appendChild(serializedDataArray);
			}
		} catch (Exception e) {
			throw new TransportException(e);
		}
	}

	@Override
	protected void processArrayList(TransportField field, ArrayList<Object> data, Type genericValueClass, Object serializedData) throws TransportException {
		try {
			if ((Boolean.class).equals(genericValueClass)) {
				for (int arrarIdx = 0; arrarIdx < data.size(); arrarIdx++) {
					Element arrayListItem = document.createElement(XML_ARRAYLIST_ITEM);
					Text textNode = document.createTextNode(((Boolean) data.get(arrarIdx)).toString());
					arrayListItem.appendChild(textNode);
					((Element) serializedData).appendChild(arrayListItem);
				}
			} else if ((Byte.class).equals(genericValueClass)) {
				for (int arrarIdx = 0; arrarIdx < data.size(); arrarIdx++) {
					Element arrayListItem = document.createElement(XML_ARRAYLIST_ITEM);
					Text textNode = document.createTextNode(((Byte) data.get(arrarIdx)).toString());
					arrayListItem.appendChild(textNode);
					((Element) serializedData).appendChild(arrayListItem);
				}
			} else if ((Character.class).equals(genericValueClass)) {
				for (int arrarIdx = 0; arrarIdx < data.size(); arrarIdx++) {
					Element arrayListItem = document.createElement(XML_ARRAYLIST_ITEM);
					Text textNode = document.createTextNode(((Character) data.get(arrarIdx)).toString());
					arrayListItem.appendChild(textNode);
					((Element) serializedData).appendChild(arrayListItem);
				}
			} else if ((Short.class).equals(genericValueClass)) {
				for (int arrarIdx = 0; arrarIdx < data.size(); arrarIdx++) {
					Element arrayListItem = document.createElement(XML_ARRAYLIST_ITEM);
					Text textNode = document.createTextNode(((Short) data.get(arrarIdx)).toString());
					arrayListItem.appendChild(textNode);
					((Element) serializedData).appendChild(arrayListItem);
				}
			} else if ((Integer.class).equals(genericValueClass)) {
				for (int arrarIdx = 0; arrarIdx < data.size(); arrarIdx++) {
					Element arrayListItem = document.createElement(XML_ARRAYLIST_ITEM);
					Text textNode = document.createTextNode(((Integer) data.get(arrarIdx)).toString());
					arrayListItem.appendChild(textNode);
					((Element) serializedData).appendChild(arrayListItem);
				}
			} else if ((Long.class).equals(genericValueClass)) {
				for (int arrarIdx = 0; arrarIdx < data.size(); arrarIdx++) {
					Element arrayListItem = document.createElement(XML_ARRAYLIST_ITEM);
					Text textNode = document.createTextNode(((Long) data.get(arrarIdx)).toString());
					arrayListItem.appendChild(textNode);
					((Element) serializedData).appendChild(arrayListItem);
				}
			} else if ((Float.class).equals(genericValueClass)) {
				for (int arrarIdx = 0; arrarIdx < data.size(); arrarIdx++) {
					Element arrayListItem = document.createElement(XML_ARRAYLIST_ITEM);
					Text textNode = document.createTextNode(((Float) data.get(arrarIdx)).toString());
					arrayListItem.appendChild(textNode);
					((Element) serializedData).appendChild(arrayListItem);
				}
			} else if ((Double.class).equals(genericValueClass)) {
				for (int arrarIdx = 0; arrarIdx < data.size(); arrarIdx++) {
					Element arrayListItem = document.createElement(XML_ARRAYLIST_ITEM);
					Text textNode = document.createTextNode(((Double) data.get(arrarIdx)).toString());
					arrayListItem.appendChild(textNode);
					((Element) serializedData).appendChild(arrayListItem);
				}
			} else if ((String.class).equals(genericValueClass)) {
				for (int arrarIdx = 0; arrarIdx < data.size(); arrarIdx++) {
					Element arrayListItem = document.createElement(XML_ARRAYLIST_ITEM);
					Text textNode = document.createTextNode((String) data.get(arrarIdx));
					arrayListItem.appendChild(textNode);
					((Element) serializedData).appendChild(arrayListItem);
				}
			} else if (isTransportable(genericValueClass)) {
				for (int arrarIdx = 0; arrarIdx < data.size(); arrarIdx++) {
					Element arrayListItem = document.createElement(XML_ARRAYLIST_ITEM);
					writeTransportable((Transportable) data.get(arrarIdx), arrayListItem);
					((Element) serializedData).appendChild(arrayListItem);
				}
			}
		} catch (Exception e) {
			throw new TransportException(e);
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	protected void serializeHashMap(TransportField field, Object objectData, Object serializedData) throws TransportException {
		try {
			if (field.isArray()) {
				HashMap<Object, Object>[] data = (HashMap<Object, Object>[]) objectData;
				Element serializedDataArrayObject = document.createElement(field.getArrayName());
				for (int dataIdx = 0; dataIdx < data.length; dataIdx++) {
					Element serializedDataArray = document.createElement(field.getName());
					processHashMap(field, data[dataIdx], field.getComponentValueType(), serializedDataArray);
					((Element) serializedDataArrayObject).appendChild(serializedDataArray);
				}
				((Element) serializedData).appendChild(serializedDataArrayObject);
			} else {
				HashMap<Object, Object> data = (HashMap<Object, Object>) objectData;
				Element serializedDataArray = document.createElement(field.getName());
				processHashMap(field, data, field.getComponentValueType(), serializedDataArray);
				((Element) serializedData).appendChild(serializedDataArray);
			}
		} catch (Exception e) {
			throw new TransportException(e);
		}
	}

	@Override
	protected void processHashMap(TransportField field, HashMap<Object, Object> data, Type genericValueClass, Object serializedData) throws TransportException {

		try {
			Iterator<?> keyIterator = data.keySet().iterator();

			if ((Boolean.class).equals(genericValueClass)) {
				while (keyIterator.hasNext()) {
					String key = (String) keyIterator.next();
					Element arrayListItem = document.createElement(XML_ARRAYLIST_ITEM);
					arrayListItem.setAttribute(XML_HASHMAP_ITEM_NAME, key);
					Text textNode = document.createTextNode(((Boolean) data.get(key)).toString());
					arrayListItem.appendChild(textNode);
					((Element) serializedData).appendChild(arrayListItem);
				}
			} else if ((Byte.class).equals(genericValueClass)) {
				while (keyIterator.hasNext()) {
					String key = (String) keyIterator.next();
					Element arrayListItem = document.createElement(XML_ARRAYLIST_ITEM);
					arrayListItem.setAttribute(XML_HASHMAP_ITEM_NAME, key);
					Text textNode = document.createTextNode(((Byte) data.get(key)).toString());
					arrayListItem.appendChild(textNode);
					((Element) serializedData).appendChild(arrayListItem);
				}
			} else if ((Character.class).equals(genericValueClass)) {
				while (keyIterator.hasNext()) {
					String key = (String) keyIterator.next();
					Element arrayListItem = document.createElement(XML_ARRAYLIST_ITEM);
					arrayListItem.setAttribute(XML_HASHMAP_ITEM_NAME, key);
					Text textNode = document.createTextNode(((Character) data.get(key)).toString());
					arrayListItem.appendChild(textNode);
					((Element) serializedData).appendChild(arrayListItem);
				}
			} else if ((Short.class).equals(genericValueClass)) {
				while (keyIterator.hasNext()) {
					String key = (String) keyIterator.next();
					Element arrayListItem = document.createElement(XML_ARRAYLIST_ITEM);
					arrayListItem.setAttribute(XML_HASHMAP_ITEM_NAME, key);
					Text textNode = document.createTextNode(((Short) data.get(key)).toString());
					arrayListItem.appendChild(textNode);
					((Element) serializedData).appendChild(arrayListItem);
				}
			} else if ((Integer.class).equals(genericValueClass)) {
				while (keyIterator.hasNext()) {
					String key = (String) keyIterator.next();
					Element arrayListItem = document.createElement(XML_ARRAYLIST_ITEM);
					arrayListItem.setAttribute(XML_HASHMAP_ITEM_NAME, key);
					Text textNode = document.createTextNode(((Integer) data.get(key)).toString());
					arrayListItem.appendChild(textNode);
					((Element) serializedData).appendChild(arrayListItem);
				}
			} else if ((Long.class).equals(genericValueClass)) {
				while (keyIterator.hasNext()) {
					String key = (String) keyIterator.next();
					Element arrayListItem = document.createElement(XML_ARRAYLIST_ITEM);
					arrayListItem.setAttribute(XML_HASHMAP_ITEM_NAME, key);
					Text textNode = document.createTextNode(((Long) data.get(key)).toString());
					arrayListItem.appendChild(textNode);
					((Element) serializedData).appendChild(arrayListItem);
				}
			} else if ((Float.class).equals(genericValueClass)) {
				while (keyIterator.hasNext()) {
					String key = (String) keyIterator.next();
					Element arrayListItem = document.createElement(XML_ARRAYLIST_ITEM);
					arrayListItem.setAttribute(XML_HASHMAP_ITEM_NAME, key);
					Text textNode = document.createTextNode(((Float) data.get(key)).toString());
					arrayListItem.appendChild(textNode);
					((Element) serializedData).appendChild(arrayListItem);
				}
			} else if ((Double.class).equals(genericValueClass)) {
				while (keyIterator.hasNext()) {
					String key = (String) keyIterator.next();
					Element arrayListItem = document.createElement(XML_ARRAYLIST_ITEM);
					arrayListItem.setAttribute(XML_HASHMAP_ITEM_NAME, key);
					Text textNode = document.createTextNode(((Double) data.get(key)).toString());
					arrayListItem.appendChild(textNode);
					((Element) serializedData).appendChild(arrayListItem);
				}
			} else if ((String.class).equals(genericValueClass)) {
				while (keyIterator.hasNext()) {
					String key = (String) keyIterator.next();
					Element arrayListItem = document.createElement(XML_ARRAYLIST_ITEM);
					arrayListItem.setAttribute(XML_HASHMAP_ITEM_NAME, key);
					Text textNode = document.createTextNode((String) data.get(key));
					arrayListItem.appendChild(textNode);
					((Element) serializedData).appendChild(arrayListItem);
				}
			} else if (isTransportable(genericValueClass)) {
				while (keyIterator.hasNext()) {
					String key = (String) keyIterator.next();
					Element arrayListItem = document.createElement(XML_ARRAYLIST_ITEM);
					arrayListItem.setAttribute(XML_HASHMAP_ITEM_NAME, key);
					writeTransportable((Transportable) data.get(key), arrayListItem);
					((Element) serializedData).appendChild(arrayListItem);
				}
			}
		} catch (Exception e) {
			throw new TransportException(e);
		}
	}

	@Override
	protected void onSerializeField(TransportField field, Object serializedData) throws TransportException {
	}

	@Override
	protected void afterSerializeField(ArrayList<TransportField> fields, Object serializedData) throws TransportException {
	}

	@Override
	protected Object parseData(byte[] dataString) throws TransportException {
		try {
			if (documentBuilder == null) {
				documentBuilder = createDocumentBuilder();
			}
			ByteArrayInputStream bais = new ByteArrayInputStream(dataString);
			Document dataDocument = documentBuilder.parse(bais);
			Node root = dataDocument.getFirstChild();
			return root;
		} catch (Exception e) {
			throw new TransportException(e);
		}
	}

	@Override
	protected Class<?> readClass(Object serializedData) throws TransportException {
		return classNames.get(((Element) serializedData).getNodeName());
	}

	@Override
	protected Object getTransportable(Object serializedData) {
		return (((Element) serializedData).getChildNodes()).item(0);
	}

	@Override
	protected boolean isTransportableArray(Object serializedData) {
		return Boolean.valueOf(((Element) serializedData).getAttribute(ROOT_IS_ARRAY));
	}

	@Override
	protected Object readTransportableArray(Object serializedData) throws TransportException {
		Object[] transpotableArray = null;
		try {
			NodeList transportableArray = ((Element) serializedData).getChildNodes();
			if (transportableArray != null && transportableArray.getLength() > 0) {
				transpotableArray = new Object[transportableArray.getLength()];

				for (int arrayIdx = 0; arrayIdx < transportableArray.getLength(); arrayIdx++) {
					transpotableArray[arrayIdx] = readTransportable(transportableArray.item(arrayIdx));
				}
			}
		} catch (Exception e) {
			throw new TransportException(e);
		}
		return transpotableArray;
	}

	@Override
	protected Object readTransportable(Object serializedData) throws TransportException {
		Object transpotableObject = null;
		try {
			Class<?> clazz = readClass(serializedData);
			if (clazz.isArray()) {
				clazz = clazz.getComponentType();
			}

			transpotableObject = clazz.newInstance();

			Element transportableObject = (Element) serializedData;
			if (transportableObject != null) {
				ArrayList<TransportField> fields = classFields.get(clazz);
				if (fields != null) {
					HashMap<String, Object> xmlData = readXMLElements((Element) serializedData);
					for (int fieldIdx = 0; fieldIdx < fields.size(); fieldIdx++) {
						TransportField field = fields.get(fieldIdx);
						String name = (field.isArray() ? field.getArrayName() : field.getName());

						Object value = null;

						if (field.isAttribute()) {
							String valueFromAttribute = ((Element) serializedData).getAttribute(name);
							value = valueFromAttribute.trim().length() == 0 ? null : valueFromAttribute;
						} else {
							value = xmlData.get(name);
						}

						if (value != null/* && isprimitiveAndHasValue(field, value)*/) {
							deserializeField(field, value, transpotableObject);
						}
					}
				}
			}
		} catch (Exception e) {
			throw new TransportException(e);
		}
		return transpotableObject;
	}

	@Override
	protected void deserializedTransportable(TransportField field, Object objectData, Object deserializedObject) throws TransportException {
		try {
			if (field.isArray()) {
				NodeList transportableXMLArray = ((Element) objectData).getChildNodes();
				Transportable[] transportableArray = new Transportable[transportableXMLArray.getLength()];
				for (int i = 0; i < transportableXMLArray.getLength(); i++) {
					transportableArray[i] = (Transportable) readTransportable(((transportableXMLArray.item(i)).getChildNodes()).item(0));
				}
				field.setValue(deserializedObject, transportableArray);
			} else {
				Transportable obj = (Transportable) readTransportable((((Element) objectData).getChildNodes()).item(0));
				field.setValue(deserializedObject, obj);
			}
		} catch (Exception e) {
			throw new TransportException(e);
		}
	}

	@Override
	protected void deserializeBoolean(TransportField field, Object objectData, Object deserializedObject) throws TransportException {
		try {
			if (field.isArray()) {
				Boolean[] fieldValue = null;
				NodeList xmlArray = ((Element) objectData).getChildNodes();
				if (xmlArray != null && xmlArray.getLength() > 0) {
					fieldValue = new Boolean[xmlArray.getLength()];

					for (int dataIdx = 0; dataIdx < xmlArray.getLength(); dataIdx++) {
						fieldValue[dataIdx] = Boolean.valueOf((xmlArray.item(dataIdx)).getTextContent());
					}
				}

				if (((Class<?>) field.getType()).getComponentType().isPrimitive()) {
					field.setValue(deserializedObject, TransporterUtil.converBooleanArray(fieldValue));
				} else {
					field.setValue(deserializedObject, fieldValue);
				}
			} else {
				field.setValue(deserializedObject, Boolean.valueOf((String) objectData));
			}
		} catch (Exception e) {
			throw new TransportException(e);
		}
	}

	@Override
	protected void deserializeByte(TransportField field, Object objectData, Object deserializedObject) throws TransportException {
		try {
			if (field.isArray()) {
				Byte[] fieldValue = null;
				NodeList xmlArray = ((Element) objectData).getChildNodes(); // getElementsByTagName(field.getName());
				if (xmlArray != null && xmlArray.getLength() > 0) {
					fieldValue = new Byte[xmlArray.getLength()];

					for (int dataIdx = 0; dataIdx < xmlArray.getLength(); dataIdx++) {
						fieldValue[dataIdx] = Byte.valueOf((xmlArray.item(dataIdx)).getTextContent());
					}
				}

				if (((Class<?>) field.getType()).getComponentType().isPrimitive()) {
					field.setValue(deserializedObject, TransporterUtil.converByteArray(fieldValue));
				} else {
					field.setValue(deserializedObject, fieldValue);
				}
			} else {
				field.setValue(deserializedObject, Byte.valueOf((String) objectData));
			}
		} catch (Exception e) {
			throw new TransportException(e);
		}
	}

	@Override
	protected void deserializeCharacter(TransportField field, Object objectData, Object deserializedObject) throws TransportException {
		try {
			if (field.isArray()) {
				Character[] fieldValue = null;
				NodeList xmlArray = ((Element) objectData).getChildNodes();
				if (xmlArray != null && xmlArray.getLength() > 0) {
					fieldValue = new Character[xmlArray.getLength()];

					for (int dataIdx = 0; dataIdx < xmlArray.getLength(); dataIdx++) {
						fieldValue[dataIdx] = (xmlArray.item(dataIdx)).getTextContent().charAt(0);
					}
				}

				if (((Class<?>) field.getType()).getComponentType().isPrimitive()) {
					field.setValue(deserializedObject, TransporterUtil.converCharacterArray(fieldValue));
				} else {
					field.setValue(deserializedObject, fieldValue);
				}
			} else {
				field.setValue(deserializedObject, ((String) objectData).charAt(0));
			}
		} catch (Exception e) {
			throw new TransportException(e);
		}
	}

	@Override
	protected void deserializeShort(TransportField field, Object objectData, Object deserializedObject) throws TransportException {
		try {
			if (field.isArray()) {
				Short[] fieldValue = null;
				NodeList xmlArray = ((Element) objectData).getChildNodes();
				if (xmlArray != null && xmlArray.getLength() > 0) {
					fieldValue = new Short[xmlArray.getLength()];

					for (int dataIdx = 0; dataIdx < xmlArray.getLength(); dataIdx++) {
						fieldValue[dataIdx] = Short.valueOf((xmlArray.item(dataIdx)).getTextContent());
					}
				}

				if (((Class<?>) field.getType()).getComponentType().isPrimitive()) {
					field.setValue(deserializedObject, TransporterUtil.converShortArray(fieldValue));
				} else {
					field.setValue(deserializedObject, fieldValue);
				}
			} else {
				field.setValue(deserializedObject, Short.valueOf((String) objectData));
			}
		} catch (Exception e) {
			throw new TransportException(e);
		}
	}

	@Override
	protected void deserializeInteger(TransportField field, Object objectData, Object deserializedObject) throws TransportException {
		try {
			if (field.isArray()) {
				Integer[] fieldValue = null;
				NodeList xmlArray = ((Element) objectData).getChildNodes();
				if (xmlArray != null && xmlArray.getLength() > 0) {
					fieldValue = new Integer[xmlArray.getLength()];

					for (int dataIdx = 0; dataIdx < xmlArray.getLength(); dataIdx++) {
						fieldValue[dataIdx] = Integer.valueOf((xmlArray.item(dataIdx)).getTextContent());
					}
				}

				if (((Class<?>) field.getType()).getComponentType().isPrimitive()) {
					field.setValue(deserializedObject, TransporterUtil.converIntegerArray(fieldValue));
				} else {
					field.setValue(deserializedObject, fieldValue);
				}
			} else {
				field.setValue(deserializedObject, Integer.valueOf((String) objectData));
			}
		} catch (Exception e) {
			throw new TransportException(e);
		}
	}

	@Override
	protected void deserializeLong(TransportField field, Object objectData, Object deserializedObject) throws TransportException {
		try {
			if (field.isArray()) {
				Long[] fieldValue = null;
				NodeList xmlArray = ((Element) objectData).getChildNodes();
				if (xmlArray != null && xmlArray.getLength() > 0) {
					fieldValue = new Long[xmlArray.getLength()];

					for (int dataIdx = 0; dataIdx < xmlArray.getLength(); dataIdx++) {
						fieldValue[dataIdx] = Long.valueOf((xmlArray.item(dataIdx)).getTextContent());
					}
				}

				if (((Class<?>) field.getType()).getComponentType().isPrimitive()) {
					field.setValue(deserializedObject, TransporterUtil.converLongArray(fieldValue));
				} else {
					field.setValue(deserializedObject, fieldValue);
				}
			} else {
				field.setValue(deserializedObject, Long.valueOf((String) objectData));
			}
		} catch (Exception e) {
			throw new TransportException(e);
		}
	}

	@Override
	protected void deserializeFloat(TransportField field, Object objectData, Object deserializedObject) throws TransportException {
		try {
			if (field.isArray()) {
				Float[] fieldValue = null;
				NodeList xmlArray = ((Element) objectData).getChildNodes();
				if (xmlArray != null && xmlArray.getLength() > 0) {
					fieldValue = new Float[xmlArray.getLength()];

					for (int dataIdx = 0; dataIdx < xmlArray.getLength(); dataIdx++) {
						fieldValue[dataIdx] = Float.valueOf((xmlArray.item(dataIdx)).getTextContent());
					}
				}

				if (((Class<?>) field.getType()).getComponentType().isPrimitive()) {
					field.setValue(deserializedObject, TransporterUtil.converFloatArray(fieldValue));
				} else {
					field.setValue(deserializedObject, fieldValue);
				}
			} else {
				field.setValue(deserializedObject, Float.valueOf((String) objectData));
			}
		} catch (Exception e) {
			throw new TransportException(e);
		}
	}

	@Override
	protected void deserializeDouble(TransportField field, Object objectData, Object deserializedObject) throws TransportException {
		try {
			if (field.isArray()) {
				Double[] fieldValue = null;
				NodeList xmlArray = ((Element) objectData).getChildNodes();
				if (xmlArray != null && xmlArray.getLength() > 0) {
					fieldValue = new Double[xmlArray.getLength()];

					for (int dataIdx = 0; dataIdx < xmlArray.getLength(); dataIdx++) {
						fieldValue[dataIdx] = Double.valueOf((xmlArray.item(dataIdx)).getTextContent());
					}
				}

				if (((Class<?>) field.getType()).getComponentType().isPrimitive()) {
					field.setValue(deserializedObject, TransporterUtil.converDoubleArray(fieldValue));
				} else {
					field.setValue(deserializedObject, fieldValue);
				}
			} else {
				field.setValue(deserializedObject, Double.valueOf((String) objectData));
			}
		} catch (Exception e) {
			throw new TransportException(e);
		}
	}

	@Override
	protected void deserializeString(TransportField field, Object objectData, Object deserializedObject) throws TransportException {
		try {
			if (field.isArray()) {
				String[] fieldValue = null;
				NodeList xmlArray = ((Element) objectData).getChildNodes();
				if (xmlArray != null && xmlArray.getLength() > 0) {
					fieldValue = new String[xmlArray.getLength()];

					for (int dataIdx = 0; dataIdx < xmlArray.getLength(); dataIdx++) {
						fieldValue[dataIdx] = (xmlArray.item(dataIdx)).getTextContent();
					}
				}

				field.setValue(deserializedObject, fieldValue);
			} else {
				field.setValue(deserializedObject, ((String) objectData));
			}
		} catch (Exception e) {
			throw new TransportException(e);
		}
	}

	@Override
	protected void deserializeDate(TransportField field, Object objectData, Object deserializedObject) throws TransportException {
		try {
			if (field.isArray()) {
				Date[] fieldValue = null;
				NodeList xmlArray = ((Element) objectData).getChildNodes();
				if (xmlArray != null && xmlArray.getLength() > 0) {
					fieldValue = new Date[xmlArray.getLength()];

					for (int dataIdx = 0; dataIdx < xmlArray.getLength(); dataIdx++) {
						fieldValue[dataIdx] = simpleDateFormat.parse((xmlArray.item(dataIdx)).getTextContent());
					}
				}

				field.setValue(deserializedObject, fieldValue);
			} else {
				field.setValue(deserializedObject, simpleDateFormat.parse(objectData.toString()));
			}
		} catch (Exception e) {
			throw new TransportException(e);
		}
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	protected void deserializeArrayList(TransportField field, Object objectData, Object deserializedObject) throws TransportException {
		try {
			Class<?> genericValueClass = (Class<?>) field.getComponentValueType();

			if (field.isArray()) {
				NodeList serializedDataArray = ((Element) objectData).getChildNodes();
				ArrayList[] deserializedDataArray = new ArrayList[serializedDataArray.getLength()];
				for (int dataIdx = 0; dataIdx < serializedDataArray.getLength(); dataIdx++) {
					ArrayList<Object> deserializedDataObject = (ArrayList<Object>) ((Class<?>) field.getRawType()).newInstance();
					readArrayList(field, serializedDataArray.item(dataIdx), genericValueClass, deserializedDataObject);
					deserializedDataArray[dataIdx] = deserializedDataObject;
				}
				field.setValue(deserializedObject, deserializedDataArray);
			} else {
				ArrayList<Object> deserializedDataObject = (ArrayList<Object>) ((Class<?>) field.getRawType()).newInstance();
				readArrayList(field, objectData, genericValueClass, deserializedDataObject);
				field.setValue(deserializedObject, deserializedDataObject);
			}
		} catch (Exception e) {
			throw new TransportException(e);
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	protected void readArrayList(TransportField field, Object valueArray, Class<?> genericValueClass, Object deserializedDataObject) throws TransportException {
		try {
			NodeList value = ((Element) valueArray).getChildNodes();

			if ((Boolean.class).equals(genericValueClass)) {
				for (int arrarIdx = 0; arrarIdx < value.getLength(); arrarIdx++) {
					((ArrayList<Boolean>) deserializedDataObject).add(Boolean.valueOf(value.item(arrarIdx).getTextContent()));
				}
			} else if ((Byte.class).equals(genericValueClass)) {
				for (int arrarIdx = 0; arrarIdx < value.getLength(); arrarIdx++) {
					((ArrayList<Byte>) deserializedDataObject).add(Byte.valueOf(value.item(arrarIdx).getTextContent()));
				}
			} else if ((Character.class).equals(genericValueClass)) {
				for (int arrarIdx = 0; arrarIdx < value.getLength(); arrarIdx++) {
					((ArrayList<Character>) deserializedDataObject).add((value.item(arrarIdx).getTextContent()).charAt(0));
				}
			} else if ((Short.class).equals(genericValueClass)) {
				for (int arrarIdx = 0; arrarIdx < value.getLength(); arrarIdx++) {
					((ArrayList<Short>) deserializedDataObject).add(Short.valueOf(value.item(arrarIdx).getTextContent()));
				}
			} else if ((Integer.class).equals(genericValueClass)) {
				for (int arrarIdx = 0; arrarIdx < value.getLength(); arrarIdx++) {
					((ArrayList<Integer>) deserializedDataObject).add(Integer.valueOf(value.item(arrarIdx).getTextContent()));
				}
			} else if ((Long.class).equals(genericValueClass)) {
				for (int arrarIdx = 0; arrarIdx < value.getLength(); arrarIdx++) {
					((ArrayList<Long>) deserializedDataObject).add(Long.valueOf(value.item(arrarIdx).getTextContent()));
				}
			} else if ((Float.class).equals(genericValueClass)) {
				for (int arrarIdx = 0; arrarIdx < value.getLength(); arrarIdx++) {
					((ArrayList<Float>) deserializedDataObject).add(Float.valueOf(value.item(arrarIdx).getTextContent()));
				}
			} else if ((Double.class).equals(genericValueClass)) {
				for (int arrarIdx = 0; arrarIdx < value.getLength(); arrarIdx++) {
					((ArrayList<Double>) deserializedDataObject).add(Double.valueOf(value.item(arrarIdx).getTextContent()));
				}
			} else if ((String.class).equals(genericValueClass)) {
				for (int arrarIdx = 0; arrarIdx < value.getLength(); arrarIdx++) {
					((ArrayList<String>) deserializedDataObject).add(value.item(arrarIdx).getTextContent());
				}
			} else if (isTransportable(genericValueClass)) {
				for (int arrarIdx = 0; arrarIdx < value.getLength(); arrarIdx++) {
					Element transportableElement = (Element) (((Element) value.item(arrarIdx)).getChildNodes()).item(0);
					((ArrayList<Transportable>) deserializedDataObject).add((Transportable) readTransportable(transportableElement));
				}
			}
		} catch (Exception e) {
			throw new TransportException(e);
		}
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	protected void deserializeHashMap(TransportField field, Object objectData, Object deserializedObject) throws TransportException {
		try {
			Class<?> genericValueClass = (Class<?>) field.getComponentValueType();

			if (field.isArray()) {
				NodeList serializedDataArray = ((Element) objectData).getChildNodes();
				HashMap[] deserializedDataArray = new HashMap[serializedDataArray.getLength()];
				for (int dataIdx = 0; dataIdx < serializedDataArray.getLength(); dataIdx++) {
					HashMap<String, Object> deserializedDataObject = (HashMap<String, Object>) ((Class<?>) field.getRawType()).newInstance();
					readHashMap(field, serializedDataArray.item(dataIdx), genericValueClass, deserializedDataObject);
					deserializedDataArray[dataIdx] = deserializedDataObject;
				}
				field.setValue(deserializedObject, deserializedDataArray);
			} else {
				HashMap<String, Object> deserializedDataObject = (HashMap<String, Object>) ((Class<?>) field.getRawType()).newInstance();
				readHashMap(field, objectData, genericValueClass, deserializedDataObject);
				field.setValue(deserializedObject, deserializedDataObject);
			}
		} catch (Exception e) {
			throw new TransportException(e);
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	protected void readHashMap(TransportField field, Object valueObject, Class<?> genericValueClass, Object deserializedDataObject) throws TransportException {
		try {
			NodeList value = ((Element) valueObject).getChildNodes();

			if ((Boolean.class).equals(genericValueClass)) {
				for (int dataIdx = 0; dataIdx < value.getLength(); dataIdx++) {
					Element item = (Element) value.item(dataIdx);
					String key = item.getAttribute(XML_HASHMAP_ITEM_NAME);
					((HashMap<String, Boolean>) deserializedDataObject).put(key, Boolean.valueOf(item.getTextContent()));
				}
			} else if ((Byte.class).equals(genericValueClass)) {
				for (int dataIdx = 0; dataIdx < value.getLength(); dataIdx++) {
					Element item = (Element) value.item(dataIdx);
					String key = item.getAttribute(XML_HASHMAP_ITEM_NAME);
					((HashMap<String, Byte>) deserializedDataObject).put(key, Byte.valueOf(item.getTextContent()));
				}
			} else if ((Character.class).equals(genericValueClass)) {
				for (int dataIdx = 0; dataIdx < value.getLength(); dataIdx++) {
					Element item = (Element) value.item(dataIdx);
					String key = item.getAttribute(XML_HASHMAP_ITEM_NAME);
					((HashMap<String, Character>) deserializedDataObject).put(key, item.getTextContent().charAt(0));
				}
			} else if ((Short.class).equals(genericValueClass)) {
				for (int dataIdx = 0; dataIdx < value.getLength(); dataIdx++) {
					Element item = (Element) value.item(dataIdx);
					String key = item.getAttribute(XML_HASHMAP_ITEM_NAME);
					((HashMap<String, Short>) deserializedDataObject).put(key, Short.valueOf(item.getTextContent()));
				}
			} else if ((Integer.class).equals(genericValueClass)) {
				for (int dataIdx = 0; dataIdx < value.getLength(); dataIdx++) {
					Element item = (Element) value.item(dataIdx);
					String key = item.getAttribute(XML_HASHMAP_ITEM_NAME);
					((HashMap<String, Integer>) deserializedDataObject).put(key, Integer.valueOf(item.getTextContent()));
				}
			} else if ((Long.class).equals(genericValueClass)) {
				for (int dataIdx = 0; dataIdx < value.getLength(); dataIdx++) {
					Element item = (Element) value.item(dataIdx);
					String key = item.getAttribute(XML_HASHMAP_ITEM_NAME);
					((HashMap<String, Long>) deserializedDataObject).put(key, Long.valueOf(item.getTextContent()));
				}
			} else if ((Float.class).equals(genericValueClass)) {
				for (int dataIdx = 0; dataIdx < value.getLength(); dataIdx++) {
					Element item = (Element) value.item(dataIdx);
					String key = item.getAttribute(XML_HASHMAP_ITEM_NAME);
					((HashMap<String, Float>) deserializedDataObject).put(key, Float.valueOf(item.getTextContent()));
				}
			} else if ((Double.class).equals(genericValueClass)) {
				for (int dataIdx = 0; dataIdx < value.getLength(); dataIdx++) {
					Element item = (Element) value.item(dataIdx);
					String key = item.getAttribute(XML_HASHMAP_ITEM_NAME);
					((HashMap<String, Double>) deserializedDataObject).put(key, Double.valueOf(item.getTextContent()));
				}
			} else if ((String.class).equals(genericValueClass)) {
				for (int dataIdx = 0; dataIdx < value.getLength(); dataIdx++) {
					Element item = (Element) value.item(dataIdx);
					String key = item.getAttribute(XML_HASHMAP_ITEM_NAME);
					((HashMap<String, String>) deserializedDataObject).put(key, item.getTextContent());
				}
			} else if (isTransportable(genericValueClass)) {
				for (int dataIdx = 0; dataIdx < value.getLength(); dataIdx++) {
					Element item = (Element) value.item(dataIdx);
					String key = item.getAttribute(XML_HASHMAP_ITEM_NAME);
					Element transportableElement = (Element) (((Element) item).getChildNodes()).item(0);
					((HashMap<String, Transportable>) deserializedDataObject).put(key, (Transportable) readTransportable(transportableElement));
				}
			}
		} catch (Exception e) {
			throw new TransportException(e);
		}
	}

	@Override
	protected byte[] stringify(Object serilizedData) throws TransportException {
		String theString = null;
		try {
			TransformerFactory tf = TransformerFactory.newInstance();
			Transformer trans = tf.newTransformer();
			StringWriter sw = new StringWriter();
			trans.transform(new DOMSource((Element) serilizedData), new StreamResult(sw));
			theString = sw.toString();
		} catch (Exception e) {
			throw new TransportException(e);
		}
		return theString.getBytes();

	}

	private HashMap<String, Object> readXMLElements(Node node) {
		HashMap<String, Object> xmlElement = new HashMap<String, Object>();
		NodeList childrens = node.getChildNodes();
		for (int i = 0; i < childrens.getLength(); i++) {
			xmlElement.put(childrens.item(i).getNodeName(), childrens.item(i));
		}
		return xmlElement;

	}
}
